#include "ringbuff.h"


RingBuff_handle_t createRingBuff(int totalsize)
{
	RingBuff_handle_t ringbuff;
	ringbuff = (RingBuff_handle_t)malloc(sizeof(struct RingBuff));
	ringbuff->source = (RingBufferDataPointer)malloc(sizeof (totalsize));
	ringbuff->write = ringbuff->source;
	ringbuff->read = ringbuff->source;
	ringbuff->writed_size = 0;
	ringbuff->tail = ringbuff->source + totalsize;
	ringbuff->size = totalsize;
	ringbuff->remain_size = totalsize;
	return ringbuff;
	
}

RingBuff_status_t writeRingBuff(RingBuff_handle_t handle,RingBufferDataPointer data,int size)
{
	
	if(handle->source == NULL ||handle == NULL)
	{
		
		return 0;
	}
	//检查剩余内存是否足够
	if(handle->remain_size > size)
	{
		//写指针在读指针前
		if(handle->write - handle->read > 0)
		{
			int writebytes = handle->tail - handle->write - size;
			//写入的数据小于写指针到内存尾部
			if(writebytes >= 0)
			{
				memcpy(handle->write,data,size);
				handle->write += size;
				
			}
			else //写入的数据大于写指针到内存尾部，需要从头部继续写入
			{
				//写入数据到尾部
				memcpy(handle->write,data,handle->tail - handle->write);
				data += handle->tail - handle->write;
				writebytes = abs(writebytes);	
				//writebytes = size - ( handle->tail - handle->write) ;
				//从头部继续写入剩余数据
				memcpy(handle->source,data,writebytes);
				handle->write = handle->source +  writebytes;
				
			}
		}
		else	//读指针在写指针前
		{
			memcpy(handle->write,data,size);
			handle->write += size;
			
		}

		//更新参数
		handle->writed_size = (handle->size + (handle->write - handle->read)) % handle->size;
		handle->remain_size = handle->size - handle->writed_size;
		return 1;	
	}
	else
	{
		
		return 0;
	}
	
}

RingBuff_status_t readRingBuffByte(RingBuff_handle_t handle,RingBufferDataPointer data)
{
	if(handle->source == NULL ||handle == NULL)
	{
		
		return 0;
	}
	
	//要读取的数据少于已经写入的数据
	if(handle->writed_size > 0)
	{
		//写指针在读指针前
		if(handle->write - handle->read > 0)
		{
			*data = handle->read[0];
			handle->read ++;
		}
		else	//读指针在写指针前
		{	
			//读取，不用从头读
			if(handle->tail - handle->read >= 1)
			{
				*data = handle->read[0];
				handle->read ++;
			}
			else 	//需要从头读
			{
				*data = handle->source[0];
				handle->read ++;
			}
		}
		//更新参数
		handle->writed_size = (handle->size + (handle->write - handle->read)) % handle->size;
		handle->remain_size = handle->size - handle->writed_size;
		return 1;
	}
	else
	{
		
		return 0;
	}
	
}

RingBuff_status_t readRingBuff(RingBuff_handle_t handle,RingBufferDataPointer data,int size)
{
	if(handle->source == NULL ||handle == NULL)
	{
		
		return 0;
	}
	
	//要读取的数据少于已经写入的数据
	if(handle->writed_size >= size)
	{
		//写指针在读指针前
		if(handle->write - handle->read > 0)
		{
			memcpy(data,handle->read,size);
			handle->read += size;
		}
		else	//读指针在写指针前
		{
			int readbytes = handle->tail - handle->read - size;
			
			//读取，不用从头读
			if(readbytes > 0)
			{
				memcpy(data,handle->read,size);
				handle->read += size;
			}
			else 	//需要从头读
			{
				memcpy(data,handle->read,handle->tail - handle->read);
				readbytes = abs(readbytes);
				data += handle->tail - handle->read;
				memcpy(data,handle->source,readbytes);
				handle->read = handle->source + readbytes;
			}
		}

		//更新参数
		handle->writed_size = (handle->size + (handle->write - handle->read)) % handle->size;
		handle->remain_size = handle->size - handle->writed_size;
		
		return 1;
	}
	else
	{
		
		return 0;
	}
	
}

RingBuff_status_t deleteRingBuff(RingBuff_handle_t handle)
{
	//需要判断指针是否空，否则free()会出错
	if(handle == NULL ||handle->source == NULL)
	{
		
		return 0;
	}
	free(handle->source);
	free(handle);
	
	return 1;
}



